package com.fuyao.cloud.admin.flow.converter;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fuyao.cloud.admin.flow.util.ExtansionPropertiesUtil;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.BaseElement;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.UserTask;
import org.flowable.editor.language.json.converter.BaseBpmnJsonConverter;
import org.flowable.editor.language.json.converter.BpmnJsonConverterContext;
import org.flowable.editor.language.json.converter.UserTaskJsonConverter;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 流程设计器任务节点属性拓展
 */
public class FyUserTaskJsonConverter extends UserTaskJsonConverter {
    /**
     * 处理人存储类型
     */
    public static final String ASSIGNEE_TYPE = "assigneeType";

    /**
     * idm 处理人
     */
    public static final String IDM_ASSIGNEE = "idmAssignee";

    /**
     * idm 候选人组
     */
    public static final String IDM_CANDIDATE_GROUPS = "idmCandidateGroups";
    /**
     * idm 候选人
     */
    public static final String IDM_CANDIDATE_USERS = "idmCandidateUsers";
    /**
     * 是否可编辑
     */
    public static final String IS_EDITDATA = "isEditdata";
    /**
     * 节点类型
     */
    public static final String NODE_TYPE = "nodeType";
    /**
     * 下一流向
     */
    public static final String NEXT_SEQUENCE_FLOW_LABEL = "nextSequenceFlow";
    /**
     * 流向
     */
    public static final String SEQUENCE_FLOW = "sequenceFlow";
    /**
     *
     */
    public static final String NEXT_USER_LABEL = "nextUser";
    /**
     * 处理人所在岗位
     */
    public static final String ASSIGNEE_GROUPS = "assigneeGroups";
    /**
     * 处理人
     */
    public static final String ASSIGNEE_USERS = "assigneeUsers";
    /**
     * 处理人查询规则
     */
    public static final String ASSIGNEE_RULES = "assigneeRules";
    /**
     * 启用字段
     */
    public static final String ENABLED_FIELDS = "enabledFields";
    /**
     * 启用按钮
     */
    public static final String ENABLED_BUTTONS = "enabledButtons";
    /**
     * 禁用按钮
     */
    public static final String DISABLED_BUTTONS = "disabledButtons";
    /**
     * 隐藏字段
     */
    public static final String HIDE_FIELDS = "hideFields";

    public static final List<String> extensionElements = Lists.newArrayList(
            ASSIGNEE_TYPE,
            IDM_ASSIGNEE,
            IDM_CANDIDATE_GROUPS,
            IDM_CANDIDATE_USERS,
            IS_EDITDATA,
            NODE_TYPE,
            NEXT_SEQUENCE_FLOW_LABEL,
            SEQUENCE_FLOW,
            NEXT_USER_LABEL,
            ASSIGNEE_GROUPS,
            ASSIGNEE_USERS,
            ASSIGNEE_RULES,
            ENABLED_FIELDS,
            ENABLED_BUTTONS,
            DISABLED_BUTTONS,
            HIDE_FIELDS
    );


    static void customFillTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap, Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {
        fillJsonTypes(convertersToBpmnMap);
        fillBpmnTypes(convertersToJsonMap);
    }

    public static void fillJsonTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap) {
        convertersToBpmnMap.put(STENCIL_TASK_USER, FyUserTaskJsonConverter.class);
    }

    public static void fillBpmnTypes(Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {
        convertersToJsonMap.put(UserTask.class, FyUserTaskJsonConverter.class);
    }

    @Override
    protected void convertElementToJson(ObjectNode propertiesNode, BaseElement baseElement, BpmnJsonConverterContext converterContext) {
        super.convertElementToJson(propertiesNode, baseElement, converterContext);
        if (baseElement instanceof UserTask) {
            Map<String, String> extensionElementValues = new HashMap<>();

            baseElement.getExtensionElements().forEach((s, elements) -> elements.forEach(extensionElement -> {
                String elementName = extensionElement.getName();
                if (extensionElements.contains(elementName)) {
                    extensionElementValues.put(elementName, extensionElement.getElementText());
                }
            }));

            extensionElementValues.forEach((key, value) -> {
                if (StringUtils.isNotBlank(value)) {
                    propertiesNode.put(key, value);
                }
            });
        }
    }

    @Override
    protected FlowElement convertJsonToElement(JsonNode elementNode, JsonNode modelNode, Map<String, JsonNode> shapeMap, BpmnJsonConverterContext converterContex) {
        FlowElement flowElement = super.convertJsonToElement(elementNode, modelNode, shapeMap, converterContex);
        this.addExtensionPropertiesElement(flowElement, elementNode);
        return flowElement;
    }

    private void addExtensionPropertiesElement(FlowElement flowElement, JsonNode elementNode) {
        if (flowElement instanceof UserTask){
            UserTask userTask = (UserTask) flowElement;
            extensionElements.forEach(name ->  ExtansionPropertiesUtil.addExtansionPropertiesElement(elementNode, userTask, name));
        }
    }
}
